package ch;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import java.io.*;
import java.nio.channels.FileChannel;
import java.util.HashSet;
import java.util.Set;

public class WebCopy
{
    private static final String ROOT_FROM = "E:/work_idea";
    private static final String ROOT_TO = "F:/swap";
    private static final String CHANGES_DIR = "/changes.txt";

    private static WebCopy INSTANCE = new WebCopy();
    private String classOutputPath;
    private String artOutPutPath;

    public static void main(String[] args)
    {
        INSTANCE.doJob();
    }

    public void doJob()
    {
        clean();
        Set<String> changes = readChanges();

        for (String change : changes)
        {
            File from = locateFromFile(change);
            File to = generateToFile(change);
            copy(from, to);
            processSubClass(from, to);
        }
    }

    private void clean()
    {
        // 清理文件
        File tmp = new File(ROOT_TO);
        for (File f : tmp.listFiles())
        {
            if (f.isDirectory())
            {
                try
                {
                    FileUtils.deleteDirectory(f);
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }

    private File generateToFile(String change)
    {
        if (change.indexOf("/src/") != -1)
        {

            if (change.endsWith(".java"))
            {
                change = StringUtils.replace(change, ".java", ".class");
            }

            change = StringUtils.replace(change, "/src/", "/WebContent/WEB-INF/classes/");
        }

        File to = new File(ROOT_TO + change);

        if (!to.getParentFile().exists())
        {
            to.getParentFile().mkdirs();
        }

        return to;
    }

    private File locateFromFile(String change)
    {
        // 源文件
        File fileFrom;

        if (change.indexOf("/src/") != -1 && change.endsWith("java"))
        {
            // 增量更新替换class
            change = StringUtils.replaceOnce(change, ".java", ".class");

            String buildFolderFile = StringUtils.replaceOnce(change, "/src/", "/build/classes/");
            fileFrom = new File(ROOT_FROM + buildFolderFile);

            // 不在buid目录下
            if (!fileFrom.exists())
            {
                // 在web-inf 下找
                String infFolderFile = StringUtils.replaceOnce(change, "/src/", "/WebContent/WEB-INF/classes/");
                fileFrom = new File(ROOT_FROM + infFolderFile);
            }

            //不在web-inf下
            if (!fileFrom.exists())
            {
                String classOutputPath = getClassesOutputPath(change);
                String artFolderFile = StringUtils.replaceOnce(change, "/src/", classOutputPath);
                fileFrom = new File(ROOT_FROM + artFolderFile);
            }

            //不在classes下
            if (!fileFrom.exists())
            {
                String classOutputPath = getArtOutPutPath(change);
                String artFolderFile = StringUtils.replaceOnce(change, "/src/", classOutputPath);
                fileFrom = new File(ROOT_FROM + artFolderFile);
            }
        }
        else
        {
            fileFrom = new File(ROOT_FROM + change);
        }

        return fileFrom;
    }

    private Set<String> readChanges()
    {
        Set<String> changes = null;
        try
        {
            // 读取SVN日志
            InputStreamReader isr = new InputStreamReader(WebCopy.class.getResourceAsStream(CHANGES_DIR));
            BufferedReader bufferedReader = new BufferedReader(isr);

            changes = new HashSet<String>();
            String s;
            while ((s = bufferedReader.readLine()) != null)
            {
                changes.add(s);
            }

            isr.close();
            bufferedReader.close();

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return changes;
    }

    /**
     * 处理内部类等文件
     *
     * @param from
     */
    private void processSubClass(File from, File to)
    {
        File parentTo = to.getParentFile();
        File parentFrom = from.getParentFile();
        String fileFromName = from.getName();

        // 不函后缀名的
        String nameWithoutName = StringUtils.substring(fileFromName, 0, fileFromName.lastIndexOf("."));

        // 内部类前缀
        String subClassPrefix = nameWithoutName + "$";

        File[] files = parentFrom.listFiles();

        if (files == null || files.length == 0)
        {
            return;
        }
        for (File file : files)
        {
            if (file.getName().startsWith(subClassPrefix))
            {
                System.err.print(file.getName());
                copy(file, new File(parentTo + "/" + file.getName()));
            }
        }

    }

    private void copy(File from, File to)
    {
        try
        {
            if (from.isDirectory())
            {
                return;
            }

            FileInputStream fileInputStream = new FileInputStream(from);
            FileOutputStream fileOutputStream = new FileOutputStream(to);

            FileChannel readChannel = fileInputStream.getChannel();
            FileChannel writeChannel = fileOutputStream.getChannel();

            readChannel.transferTo(0, readChannel.size(), writeChannel);

            readChannel.close();
            writeChannel.close();

            PrintStream printStream = System.out;

            if (from.getName().endsWith(".properties") || from.getName().endsWith(".xml"))
            {
                printStream = System.err;
            }

            printStream.println("from [" + from.getAbsolutePath() + "]");
            printStream.println("to   [" + to.getAbsolutePath() + "]");
            printStream.println("-------------------------------");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    private String getClassesOutputPath(String path)
    {
        if (classOutputPath != null)
        {
            return classOutputPath;
        }
        else
        {
            String[] arr = StringUtils.split(path, "/");
            String projectName = arr[0];

            classOutputPath = "/classes/artifacts/" + projectName + "_war_exploded/WEB-INF/classes/";
            return classOutputPath;
        }
    }

    private String getArtOutPutPath(String path)
    {
        if (artOutPutPath != null)
        {
            return artOutPutPath;
        }
        else
        {
            String[] arr = StringUtils.split(path, "/");
            String projectName = arr[0];

            artOutPutPath = "/out/artifacts/" + projectName + "_war_exploded/WEB-INF/classes/";
            return artOutPutPath;
        }
    }

}
